package com.adv.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.adv.mapper.LoginlogMapper;
import com.adv.mapper.PRoleMapper;
import com.adv.mapper.PUserRoleLinkMapper;
import com.adv.mapper.UserMapper;
import com.adv.model.Loginlog;
import com.adv.model.LoginlogExample;
import com.adv.model.LoginlogExample.Criteria;
import com.adv.model.PRole;
import com.adv.model.PRoleSqlParam;
import com.adv.model.PUserRoleLink;
import com.adv.model.PUserRoleLinkSqlParam;
import com.adv.model.User;
import com.adv.model.UserSqlParam;
import com.adv.util.Constant;
import com.adv.util.DozerUtil;
import com.adv.util.PasswordUtil;
import com.adv.util.RequestUtil;
import com.adv.vo.LoginForm;
import com.adv.vo.LoginlogForm;
import com.adv.vo.RoleForm;
import com.adv.vo.UserForm;

@Component
public class UserService {

	@Autowired
	private UserMapper adminMapper;

	@Autowired
	private PRoleMapper roleMapper;

	@Autowired
	private PUserRoleLinkMapper userRoleLinkMapper;

	@Autowired
	private LoginlogMapper loginlogMapper;

	/**
	 * 登录
	 * 
	 * @param form
	 * @return
	 */
	public Map<String, Object> login(LoginForm form) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		UsernamePasswordToken token = new UsernamePasswordToken(form.getUsername(), form.getPassword(), "");
		token.setRememberMe(Constant.REMEMBERENABLE.equals(form.getRemember()));
		Subject subject = SecurityUtils.getSubject();
		try {
			subject.login(token);
			if (subject.isAuthenticated()) {
				// System.out.println("logined uid=" +
				// subject.getSession().getAttribute("uid"));
				// if (PasswordUtil.verify(form.getPassword(),
				// admin.getPassword()))
				// {
				// if (Constant.REMEMBERENABLE.equals(form.getRemember())) {
				// // 设置cookie，保留7天
				// setCookie(EncryptorUtil.encrypt(admin.getUsername() + "|" +
				// admin.getId()), 7 * 86400);
				// }

				UserSqlParam param = new UserSqlParam();
				param.createCriteria().andUsernameEqualTo(form.getUsername());
				List<User> list = adminMapper.selectByParam(param);
				User admin = list.get(0);
				addLoginlog(admin.getId());
				// RequestUtil.getSession().setAttribute(LoginInterceptor.USERSESSIONKEY,
				// admin);
				resultMap.clear();
			}
		} catch (UnknownAccountException e) {
			resultMap.put("username", "用户名错误");
		} catch (Exception e) {
			resultMap.put("password", "密码错误");
		}
		return resultMap;
	}

	private void addLoginlog(Integer id) {
		Loginlog loginlog = new Loginlog();
		loginlog.setUid(id);
		loginlog.setLogintime(Constant.SDFCOMMON.format(new Date()));
		loginlog.setIp(RequestUtil.getIP());
		loginlogMapper.insertSelective(loginlog);
	}

	public LoginlogForm getLastLoginlog() {
		if (SecurityUtils.getSubject().isAuthenticated()) {
			LoginlogExample example = new LoginlogExample();
			example.setOrderByClause("logintime desc");
			example.setLimit("0,1");
			Criteria createCriteria = example.createCriteria();
			Object uidObj = SecurityUtils.getSubject().getSession(true).getAttribute("uid");
			Integer userId = Integer.parseInt(uidObj.toString());
			createCriteria.andUidEqualTo(userId);
			List<Loginlog> list = loginlogMapper.selectByExample(example);
			if (!CollectionUtils.isEmpty(list)) {
				LoginlogForm form = DozerUtil.mapObj(list.get(0), LoginlogForm.class);
				form.setCount(loginlogMapper.countByExample(example));
				return form;
			}
		}
		return null;
	}

	/**
	 * 退出登录
	 */
	public void loginout() {
		SecurityUtils.getSubject().logout();
		// setCookie("", 0);
		// RequestUtil.getSession().removeAttribute(LoginInterceptor.USERSESSIONKEY);
	}

	// 用户登录相关cookie
	// private void setCookie(String value, int maxAge) {
	// Cookie cookie = new Cookie(LoginInterceptor.USERCOOKIEKEY, value);
	// cookie.setHttpOnly(true);
	// cookie.setMaxAge(maxAge);
	// RequestUtil.getResponse().addCookie(cookie);
	// }

	public List<User> getUser() {
		return adminMapper.selectByParam(new UserSqlParam());
	}

	public UserForm initForm(UserForm form) {
		if (null == form) {
			form = new UserForm();
		}
		PRoleSqlParam param = new PRoleSqlParam();
		param.createCriteria().andEnableEqualTo(true);
		List<PRole> roles = roleMapper.selectByParam(param);
		form.setRoles(DozerUtil.mapList(roles, RoleForm.class));
		if (null != form.getId()) {
			User user = adminMapper.selectByPrimaryKey(form.getId());
			roles = user.getRoles();
			user.setRoles(new ArrayList<PRole>());
			user.setPassword(null);
			DozerUtil.mapObj(user, form);
			if (!CollectionUtils.isEmpty(roles)) {
				for (PRole role : roles) {
					for (RoleForm roleForm : form.getRoles()) {
						if (role.getId().equals(roleForm.getId())) {
							roleForm.setChecked(true);
							break;
						}
					}
				}
			}
		}
		return form;
	}

	public Map<String, Object> saveUser(UserForm form) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.put(Constant.RESULTKEY, Constant.FAILURE);
		if (null != form) {
			if (StringUtils.isEmpty(form.getRegistertime())) {
				form.setRegistertime(Constant.SDFCOMMON.format(new Date()));
			}
			User record = DozerUtil.mapObj(form, User.class);
			if (!StringUtils.isEmpty(form.getPassword())) {
				record.setPassword(PasswordUtil.generate(form.getPassword()));
			}
			if (null != record.getId()) {
				int num = adminMapper.updateByPrimaryKeySelective(record);
				if (num == 1) {
					resultMap.put(Constant.RESULTKEY, Constant.SUCCESS);
				}
			} else {
				int num = adminMapper.insertSelective(record);
				if (num == 1) {
					resultMap.put(Constant.RESULTKEY, Constant.SUCCESS);
				}
			}
			if (Constant.SUCCESS.equals(resultMap.get(Constant.RESULTKEY))) {
				PUserRoleLinkSqlParam param = new PUserRoleLinkSqlParam();
				param.createCriteria().andUseridEqualTo(record.getId());
				userRoleLinkMapper.deleteByParam(param);
				if (null != form.getCheckedRoles()) {
					List<PUserRoleLink> userRoleLinks = new ArrayList<PUserRoleLink>();
					for (Integer checkedRoleId : form.getCheckedRoles()) {
						PUserRoleLink link = new PUserRoleLink();
						link.setRoleid(checkedRoleId);
						link.setUserid(record.getId());
						userRoleLinks.add(link);
					}
					userRoleLinkMapper.insertBatchBySelective(userRoleLinks, userRoleLinks.get(0));
				}
			}
		}
		return resultMap;
	}

}
